use serde::{Deserialize, Serialize};

/// 接收到的RF数据包及相关元数据
#[derive(Serialize, Deserialize, Debug)]
pub struct Rxpk {
    /// 数据包接收的UTC时间，us精度，ISO 8601紧凑格式
    pub time: Option<String>,
    /// 数据包接收的GPS时间，自1980年1月6日以来的毫秒数
    pub tmms: Option<u64>,
    /// "RX完成"事件的内部时间戳（32位无符号整数）
    pub tmst: Option<u64>,
    /// RX中心频率，单位为MHz（无符号浮点数，Hz精度）
    pub freq: f64,
    /// 用于接收的集中器“IF”通道（无符号整数）
    pub chan: u8,
    /// 用于接收的集中器“RF”链（无符号整数）
    pub rfch: u8,
    /// CRC状态：1 = OK，-1 = 失败，0 = 无CRC
    pub stat: i8,
    /// 调制标识符 "LORA" 或 "FSK"
    pub modu: String,
    /// LoRa速率标识符或FSK速率
    pub datr: serde_json::Value, // 可以是字符串或数字
    /// LoRa ECC编码速率标识符
    pub codr: Option<String>,
    /// RSSI，单位为dBm（有符号整数，1 dB精度）
    pub rssi: i32,
    /// Lora SNR比率，单位为dB（有符号浮点数，0.1 dB精度）
    pub lsnr: f32,
    /// RF数据包有效负载大小，单位为字节（无符号整数）
    pub size: u32,
    /// 基础64编码的RF数据包有效负载，带填充
    pub data: String,
}

/// 网关状态信息
#[derive(Serialize, Deserialize, Debug)]
pub struct Stat {
    /// 网关的UTC“系统”时间，ISO 8601扩展格式
    pub time: String,
    /// 网关的GPS纬度，单位为度（浮点数，N为正）
    pub lati: Option<f64>,
    /// 网关的GPS经度，单位为度（浮点数，E为正）
    pub long: Option<f64>,
    /// 网关的GPS海拔，单位为米（整数）
    pub alti: Option<i32>,
    /// 接收的无线电数据包数量（无符号整数）
    pub rxnb: Option<u32>,
    /// 接收的有效PHY CRC的无线电数据包数量
    pub rxok: Option<u32>,
    /// 转发的无线电数据包数量（无符号整数）
    pub rxfw: Option<u32>,
    /// 上行数据包确认的百分比
    pub ackr: Option<f64>,
    /// 接收到的下行数据包数量（无符号整数）
    pub dwnb: Option<u32>,
    /// 发出的数据包数量（无符号整数）
    pub txnb: Option<u32>,
}

/// PUSH_DATA数据结构
#[derive(Serialize, Deserialize, Debug)]
pub struct PushData {
    /// 接收到的RF数据包数组
    pub rxpk: Option<Vec<Rxpk>>,
    /// 网关状态信息
    pub stat: Option<Stat>,
}

/// 下行数据包及其相关元数据
#[derive(Serialize, Deserialize, Debug)]
pub struct Txpk {
    /// 立即发送数据包（将忽略tmst和time）
    pub imme: Option<bool>,
    /// 在某个时间戳值发送数据包（将忽略time）
    pub tmst: Option<u32>,
    /// 在某个GPS时间发送数据包（需要GPS同步）
    pub tmms: Option<u64>,
    /// TX中心频率，单位为MHz（无符号浮点数，Hz精度）
    pub freq: f64,
    /// 用于发送的集中器“RF”链（无符号整数）
    pub rfch: Option<u8>,
    /// TX输出功率，单位为dBm（无符号整数，dBm精度）
    pub powe: Option<u8>,
    /// 调制标识符 "LORA" 或 "FSK"
    pub modu: String,
    /// LoRa速率标识符或FSK速率
    pub datr: Option<Datr>,
    /// LoRa ECC编码速率标识符
    pub codr: Option<String>,
    /// FSK频率偏移（无符号整数，单位为Hz）
    pub fdev: Option<u32>,
    /// LoRa调制极化反转
    pub ipol: Option<bool>,
    /// RF前导码大小（无符号整数）
    pub prea: Option<u16>,
    /// RF数据包有效负载大小，单位为字节（无符号整数）
    pub size: u16,
    /// 基础64编码的RF数据包有效负载，带填充(MAC物理层负载包)
    pub data: String,
    /// 如果为true，则禁用物理层的CRC（可选）
    pub ncrc: Option<bool>,
}

/// 数据速率（可以是字符串或数字）
#[derive(Serialize, Deserialize, Debug)]
#[serde(untagged)]
pub enum Datr {
    /// LoRa速率标识符
    Lora(String),
    /// FSK速率，单位为bps
    Fsk(u32),
}

/// PULL_RESP数据结构封装
#[derive(Serialize, Deserialize, Debug)]
pub struct PullResp {
    /// 下行数据包及其相关元数据
    pub txpk: Txpk,
}



/// TX_ACK 数据结构封装
#[derive(Serialize, Deserialize, Debug)]
pub struct TXACK {
    /// 下行数据包的状态信息
    pub txpk_ack: TxpkAck,
}

/// TX_ACK数据结构
#[derive(Serialize, Deserialize, Debug)]
pub struct TxpkAck {
    /// 下行数据包的状态信息
    pub error: TxError,
}


/// 下行数据包的状态信息枚举
#[derive(Serialize, Deserialize, Debug)]
pub enum TxError {
    /// 数据包已经为下行数据包编程
    None,
    /// 由于已经太晚，因此拒绝为此数据包编程
    TooLate,
    /// 由于下行数据包时间戳过早，因此拒绝
    TooEarly,
    /// 由于在请求的时间范围内已经编程了数据包，因此拒绝
    CollisionPacket,
    /// 由于在请求的时间范围内已经计划了信标，因此拒绝
    CollisionBeacon,
    /// 由于请求的频率不受 TX RF 链支持，因此拒绝
    TxFreq,
    /// 由于请求的功率不受网关支持，因此拒绝
    TxPower,
    /// 由于 GPS 解锁，因此拒绝使用 GPS 时间戳
    GpsUnlocked,
}
